package com.tzt.controller.common;

import com.tzt.common.BaseController;
import com.tzt.contents.CacheKeyConstant;
import com.tzt.contents.Constantpool;
import com.tzt.contents.ErrorCodeConstant;
import com.tzt.entity.ProductEntity;
import com.tzt.entity.TerminalHandleEntity;
import com.tzt.exception.InnerException;
import com.tzt.service.*;
import com.tzt.util.GetCacheUtil;
import com.tzt.util.NomalUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 
 * <描述>公共Controller
 * @author Double
 * @version [版本号, 2017年12月20日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@RestController
public class CommonController extends BaseController
{
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private SpmHandleService spmHandleService;

    @Autowired
    private UserService userService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private GetCacheUtil getCacheUtil;

    @Autowired
    private ShopUserService shopUserService;

    @Autowired
    private ProductService productService;

    @Autowired
    private PooboService pooboService;

    /**
     * 开门
     * @param openid 微信唯一id
     * @param alipayId 支付宝唯一id
     * @param registrationId app极光注册id
     * @param serialNumber 序列号
     * @param userId 用户id
     * @param token 验签
     * @param scanType 终端类型
     * @param clientType 调用方式 微信：weixin、app：app、支付宝：alipay 人脸：face
     * @param miniOpenId 小程序openId
     * @param cameraMarker 摄像头标识
     * @return
     */
    @RequestMapping(value = "/api/openDoor", method = RequestMethod.POST)
    public Map<String, Object> openDoor(String openid,String alipayId, String registrationId,String serialNumber, String userId, String token,
            String scanType, String clientType,String miniOpenId, String cameraMarker)
    {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("clientType",clientType);
        try
        {
            // 柜子
            if (Constantpool.TERMINAL_SCANTYPE.equals(scanType))
            {
                logger.info("柜子开门 openid：" + openid + " <==> serialNumber：" + serialNumber + " <==> userId：" + userId
                        + " <==> clientType：" + clientType + " <==> token：" + token + " <==> cameraMarker: " + cameraMarker);
                userService.userOpenDoor(openid,alipayId,registrationId, token, userId, serialNumber, map, clientType,miniOpenId);
            }
            // 超市
            else if (Constantpool.SPM_SCANTYPE.equals(scanType))
            {
                logger.info("超市开门 serialNumber：" + serialNumber + " <==> userId：" + userId + " <==> token：" + token + " <==> cameraMarker: " + cameraMarker);
                spmHandleService.SpmOpenDoor(openid, serialNumber,alipayId,registrationId,  userId, token, map,clientType, cameraMarker);
            }
        }
        catch (NumberFormatException e)
        {
            logger.error("开门失败：", e);
            return paramFailedMessage();
        }
        catch (InnerException e)
        {
            logger.error("开门失败：", e);
            return failedData(map, e.getErrorCode(), e.getMessage());
        }
        catch (Exception e)
        {
            logger.error("开门失败：", e);
            return failedData(map, ErrorCodeConstant.FAILED, ErrorCodeConstant.FAILED_MSG);
        }
        return successData(map);
    }

    /**
     * 调用方式 微信：weixin、app：app、支付宝：alipay 人脸：face
     * @param terminalId
     * @param userId
     * @param token
     * @param clientType
     * @param returnParams
     * @param successNotifyUrl
     * @return
     */
    @RequestMapping(value = "/openDoorApi", method = RequestMethod.POST)
    public Map<String, Object> openDoorApi(String terminalId, String userId, String token, String clientType,
            String returnParams,String successNotifyUrl,String mobile,String username)
    {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("returnParams",returnParams);
        try
        {
            spmHandleService.openDoorApi(terminalId, userId, token, clientType, returnParams, successNotifyUrl,mobile,username);
        }
        catch (NumberFormatException e)
        {
            logger.error("开门失败：", e);
            return paramFailedMessage();
        }
        catch (InnerException e)
        {
            logger.error("开门失败：", e);
            return failedData(map, e.getErrorCode(), e.getMessage());
        }
        catch (Exception e)
        {
            logger.error("开门失败：", e);
            return failedData(map, ErrorCodeConstant.FAILED, ErrorCodeConstant.FAILED_MSG);
        }
        return successData(map);
    }

    /**
     * 支付回调（根据orderNumber更新订单支付状态） <功能详细描述>
     * @param userId 用户id
     * @param orderNumber 订单编号
     * @param payType 支付类型
     * @param tradeNo 支付流水号
     * @param openid 微信公众号openid
     * @param buyerUserId 支付宝生活号唯一id
     * @param scanType 类型 0：柜子  1：超市
     * @param paymentAmount 实付金额
     * @param isWithhold 是否免密： 1:是 0:不是
     * @return
     */
    @RequestMapping(value = "/api/payBack", method = RequestMethod.POST)
    public Map<String, Object> payBack(String userId, String orderNumber, String payType, String tradeNo, String openid,
            String buyerUserId, String scanType, String paymentAmount, String isWithhold)
    {
        logger.info("回调开始userId:" + userId + " <==>orderNumber:" + orderNumber + " <==>payType:" + payType
                + " <==>tradeNo:" + tradeNo + " <==>openid:" + openid + " <==>buyerUserId:" + buyerUserId
                + " <==>scanType:" + scanType + " <==>paymentAmount:"+paymentAmount);
        Map<String, Object> map = new HashMap<String, Object>();
        try
        {
            // 柜子
            if (Constantpool.TERMINAL_SCANTYPE.equals(scanType))
            {
                logger.info("柜子支付回调 orderNumber：" + orderNumber + " <==> openid：" + openid + " <==> buyerUserId："
                        + buyerUserId + " <==> tradeNo：" + tradeNo);
                orderService.updatePayStatus(orderNumber, openid, buyerUserId, tradeNo,payType, paymentAmount,isWithhold);
            }
            // 超市
            else if (Constantpool.SPM_SCANTYPE.equals(scanType))
            {
                logger.info("userId：" + userId + " <==> payType：" + payType + " <==> tradeNo：" + tradeNo
                        + " <==> openid：" + openid + " <==> buyerUserId：" + buyerUserId);
                spmHandleService.SpmPayBack(userId, orderNumber, payType, tradeNo, openid, buyerUserId ,paymentAmount, isWithhold);
            }
        }
        catch (NumberFormatException e)
        {
            logger.error("支付回调 失败：", e);
            return paramFailedMessage();
        }
        catch (InnerException e)
        {
            logger.error("支付回调 失败：", e);
            return failedData(map, e.getErrorCode(), e.getMessage());
        }
        catch (Exception e)
        {
            logger.error("支付回调 失败：", e);
            return failedData(map, ErrorCodeConstant.FAILED, ErrorCodeConstant.FAILED_MSG);
        }
        return successData(map);

    }

    /**
     * 京东支付回调
     * @param groupCode
     * @param sign
     * @param cipherJson
     * @return
     */
    @RequestMapping(value = "/api/jdPayBack", method = RequestMethod.POST)
    public Map<String, Object> jdPayBack(String groupCode, String sign, String cipherJson)
    {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("success",true);
        try{
            spmHandleService.jdPayBack(groupCode, sign, cipherJson);
        }catch (Exception e){
            result.put("success",false);
        }
        return result;


    }

    /**
     * 关门
     * @param labs 标签
     * @param serialNumber 序列号
     * @param userId 用户id
     * @param clientType 调用方式 微信：weixin、app：app、支付宝：alipay
     * @param videoStartTime 视频开始时间
     * @param videoEndTime 视频结束时间
     * @return
     */
    @RequestMapping(value = "/api/closeDoor", method = RequestMethod.POST)
    public Map<String, Object> closeDoor(String labs, String serialNumber, String userId, String clientType,
            String videoStartTime, String videoEndTime)
    {

        Map<String, Object> map = new HashMap<String, Object>();
        try
        {
            // 判断操作用户
            TerminalHandleEntity terminalHandle = getCacheUtil.getTerminalHandle(serialNumber);
            getCacheUtil.setTerminalHandle(serialNumber, null);
            getCacheUtil .deleteStringRedisVal(CacheKeyConstant.OPEN_USERID + userId);
            logger.info("操作用户：" + terminalHandle);
            if(NomalUtil.isNullOrEmpty(terminalHandle)){
                logger.error("关门失败  closeDoor serialNumber：" + serialNumber + " userId:" + userId + " labs:" + labs);
                throw new InnerException(ErrorCodeConstant.FAILED, "关门失败，重复提交。");
            }
            if (terminalHandle.checkShopUser())
            {
                logger.info("商家关门 labs" + labs + " <==> serialNumber:" + serialNumber + " <==> terminalHandle："
                        + terminalHandle);
                userService.shopUserCloseDoor(terminalHandle, labs, userId, videoStartTime, videoEndTime, map);
            }
            if (terminalHandle.checkUser())
            {
                logger.info("用户关门 labs" + labs + " <==> serialNumber" + userId + " <==> clientType" + clientType
                        + " <==> terminalHandle：" + terminalHandle);
                userService.userCloseDoor(terminalHandle, labs, userId, clientType, videoStartTime, videoStartTime, map);
            }

        }
        catch (NumberFormatException e)
        {
            logger.error("关门失败  closeDoor serialNumber：" + serialNumber + " userId:" + userId + " labs:" + labs, e);
            return paramFailedMessage();
        }
        catch (InnerException e)
        {
            logger.error("关门失败 closeDoor serialNumber：", e);
            return failedData(map, e.getErrorCode(), e.getMessage());
        }
        catch (Exception e)
        {
            logger.error("关门失败  closeDoor serialNumber：" + " userId:" + userId + " labs:" + labs, e);
            return failedData(map, "1", "失败");
        }
        return successData(map);
    }

    /**
     * 商家柜子开门
     * @param shopUserId 商家用户id
     * @param terminalId 终端id
     * @return
     */
    @RequestMapping(value = "/api/shopUserOpenDoor", method = RequestMethod.POST)
    public Map<String, Object> shopUserOpenDoor(String shopUserId, String terminalId)
    {
        Map<String, Object> map = new HashMap<String, Object>();
        try
        {
            shopUserService.shopUserOpenDoor(shopUserId, terminalId);
        }
        catch (NumberFormatException e)
        {
            logger.error("商家开门失败  shopUserId：" + shopUserId + "、terminalId:" + terminalId, e);
            return paramFailedMessage();
        }
        catch (InnerException e)
        {
            logger.error("商家开门失败  shopUserId：" + shopUserId + "、terminalId:" + terminalId, e);
            return failedData(map, e.getErrorCode(), e.getMessage());
        }
        catch (Exception e)
        {
            logger.error("商家开门 失败 shopUserId：" + shopUserId + "、terminalId:" + terminalId, e);
            return failedData(map, ErrorCodeConstant.FAILED, "开门失败");
        }
        return successData(map);
    }

    /**
     * 发送验证码
     * @param mobile 手机号
     * @param smsType 发送方式
     * @param clientIp 客户端ip
     * @return
     */
    @RequestMapping(value = "/api/smsCode", method = RequestMethod.POST)
    public Map<String, Object> smsCode(String mobile, String smsType ,String clientIp)
    {
        Map<String, Object> map = new HashMap<String, Object>();
        try
        {
            userService.smsCode(mobile, smsType, clientIp, map);
        }
        catch (NumberFormatException e)
        {
            logger.error("发送验证码 smsCode:" + mobile + ":" + smsType, e);
            return paramFailedMessage();
        }
        catch (InnerException e)
        {
            logger.error("发送验证码 smsCode:" + mobile + ":" + smsType, e);
            return failedData(map, e.getErrorCode(), e.getMessage());
        }
        catch (Exception e)
        {
            logger.error("发送验证码 smsCode:" + mobile + ":" + smsType, e);
            return failedData(map, ErrorCodeConstant.FAILED, ErrorCodeConstant.FAILED_MSG);
        }
        return successData(map);
    }

    /**
     * 开门通知
     * @param serialNumber 序列号
     * @param userId 用户id
     * @param switchStatus
     * @return
     */
    @RequestMapping(value = "/api/openDoorNotification", method = RequestMethod.POST)
    public Map<String, Object> openDoorNotification(String serialNumber, String userId, String switchStatus)
    {
        Map<String, Object> map = new HashMap<String, Object>();
        try
        {
            if("0".equals(userId))
            {
                spmHandleService.apiOpenDoorNotification(serialNumber, userId, switchStatus, map);
            }
            else
            {
                userService.openDoorNotification(serialNumber, userId, switchStatus, map);
            }

        }
        catch (NumberFormatException e)
        {
            logger.error("开门通知:" + serialNumber + ":" + userId, e);
            return paramFailedMessage();
        }
        catch (InnerException e)
        {
            logger.error("开门通知:" + serialNumber + ":" + userId, e);
            return failedData(map, e.getErrorCode(), e.getMessage());
        }
        catch (Exception e)
        {
            logger.error("开门通知:" + serialNumber + ":" + userId, e);
            return failedData(map, ErrorCodeConstant.FAILED, ErrorCodeConstant.FAILED_MSG);
        }
        return successData(map);
    }

    /**
     * 
     * <功能详细描述>修改配置文件刷新缓存
     * @return
     * @see [类、类#方法、类#成员]
     */
    @RequestMapping(value = "/api/refreshCache", method = RequestMethod.GET)
    public String refreshCache()
    {
        return shopUserService.refreshCache();
    }

    /**
     * 查询终端商品详情
     * @param serialNumber 序列号
     * @return
     */
    @RequestMapping(value = "/api/getTerminalProductDetail", method = RequestMethod.POST)
    public Map<String, Object> getTerminalProductDetail(String serialNumber)
    {
        Map<String, Object> map = new HashMap<String, Object>();
        try
        {
            List<ProductEntity> terminalProductDetail = productService.getTerminalProductDetail(serialNumber);
            map.put("productDetail",terminalProductDetail);
        }
        catch (NumberFormatException e)
        {
            logger.error("查询终端商品详情失败:", e);
            return paramFailedMessage();
        }
        catch (InnerException e)
        {
            logger.error("查询终端商品详情失败:", e);
            return failedData(map, e.getErrorCode(), e.getMessage());
        }
        catch (Exception e)
        {
            logger.error("查询终端商品详情失败:", e);
            return failedData(map, ErrorCodeConstant.FAILED, ErrorCodeConstant.FAILED_MSG);
        }
        return successData(map);
    }

    /**
     * 获取物联网卡access_token
     * @param userId 用户id
     * @param token 验签
     * @return
     */
    @RequestMapping(value = "/api/getNetworkAccessToken", method = RequestMethod.POST)
    public Map<String, Object> getNetworkAccessToken(String userId, String token)
    {
        Map<String, Object> map = new HashMap<String, Object>();
        try
        {
            userService.getNetworkAccessToken( userId, token, map);
        }
        catch (NumberFormatException e)
        {
            logger.error("获取物联网卡token失败:", e);
            return paramFailedMessage();
        }
        catch (InnerException e)
        {
            logger.error("获取物联网卡token失败:", e);
            return failedData(map, e.getErrorCode(), e.getMessage());
        }
        catch (Exception e)
        {
            logger.error("获取物联网卡token失败:", e);
            return failedData(map, ErrorCodeConstant.FAILED, ErrorCodeConstant.FAILED_MSG);
        }
        return successData(map);
    }



}
